<?php
/**
  * Mar 10, 2008
  *
  * Coded by: Ropu
  *
  */

define('ENTER', "\r\n");
define('DOUBLE_ENTER', ENTER.ENTER);  

  
class Http {
  
  static public function get($url, $getargs=array(), $timeout=false) {
    $headers = array();
//    $headers[] = "Authorization: Basic ".base64_encode(
//    $this->merchant_id.':'.$this->merchant_key);
//    $headers[] = "Content-Type: application/xml; charset=UTF-8";
//    $headers[] = "Accept: application/xml; charset=UTF-8";
    $headers[] = "User-Agent: OpenSocial HttpRequest (v0.1beta/ropu)";
    $args = (strpos($url, '?') === false)?'?':'&';
    foreach($getargs as $name => $value) {
      $args .= urlencode($name) . "=" . urlencode($value) . "&";
     }
    return Http::sendReq('GET', $url . $args, $headers, '', $timeout);
  }

  static public function post($url, $postargs=array(), $timeout=false) {
    $headers = array();
//    $headers[] = "Authorization: Basic ".base64_encode(
//    $this->merchant_id.':'.$this->merchant_key);
//    $headers[] = "Content-Type: application/xml; charset=UTF-8";
//    $headers[] = "Accept: application/xml; charset=UTF-8";
    $headers[] = "User-Agent: OpenSocial HttpRequest (v0.1beta/ropu)";
    $args = '';
    foreach($postargs as $name => $value) {
      $args .= urlencode($name) . "=" . urlencode($value) . "&";
    }
    return Http::sendReq('POST', $url, $headers, $args, $timeout);
  }
  
  static public function sendReq($type='GET', $url, $header_arr, $postargs, 
                                                               $timeout=false) {
$timeout = 25;
  // Get the curl session object
   $ch = curl_init($url);
   Log::basic($type . " " .$url . " Args: ". $postargs);
   switch(strtoupper($type)) {
   // Set the POST options.
     case 'POST':
       curl_setopt($ch, CURLOPT_POST, true);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $postargs);
       break;
     case 'GET':
     default:
       break;
   }
   
   curl_setopt($ch, CURLOPT_HTTPHEADER, $header_arr);
   curl_setopt($ch, CURLOPT_HEADER, true);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//   if(!empty(certPath) && file_exists(Http::certPath)) {
//     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
//     curl_setopt($ch, CURLOPT_CAINFO, $this->certPath);
//   }
//   else {
//     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//   }
//
//   if(is_array($this->proxy) && count($this->proxy)) {
//      curl_setopt($ch, CURLOPT_PROXY, 
//                         $this->proxy['host'] . ":" . $this->proxy['port']);
//   }

//      curl_setopt($ch, CURLOPT_PROXY, "proxy.corp.globant.com:3128");

  if($timeout != false){
     curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
   }
   // Do the POST and then close the session
   $response = curl_exec($ch);
   if (curl_errno($ch)) {
     $error = curl_error($ch);
     Log::medium($error);
     curl_close($ch);
     throw new HttpException($error, 500);
   } else {
     curl_close($ch);
   }
//   $http_obj = http_parse_message($response);
//   http
//   print_r($http_obj);
   $heads = Http::parse_headers($response);
   $body = Http::get_body_x($response);
         
   // Get HTTP Status code from the response
   $status_code = array();
   preg_match('/\d\d\d/', $heads[0], $status_code);
   
   // Check for errors
   switch( $status_code[0] ) {
     case 200:
       // Success
         Log::basic($response);          
         return $body;
       break;
//     case 400:
//         Log::medium($response);
//         throw new HttpException(htmlentities($body), 400);
//       break;
//     case 403:
//         Log::medium($response);
//         throw new HttpException(htmlentities($body), 403);
//       break;
//     case 404:
//         Log::medium($response);
//         throw new HttpException(htmlentities($body), 403);
//       break;
//     case 503:
//         Log::medium($response);
//         throw new HttpException(htmlentities($body), 503);
//       break;
     default:
         Log::medium($response);
         throw new HttpException(htmlentities($body), $status_code[0]);
//         return array("ERR", htmlentities($body));
       break;
   }
 }

// Private functions
// Function to get HTTP headers,
// will also work with HTTP 200 status added by some proxy servers
    /**
     * @access private
     */
  static protected function parse_headers($message) {
    $head_end = strpos($message, DOUBLE_ENTER);
    $headers = Http::get_headers_x(substr($message,0,
                                           $head_end + strlen(DOUBLE_ENTER)));
    if(!is_array($headers) || empty($headers)){
      return null;
    }
    if(!preg_match('%[HTTP/\d\.\d] (\d\d\d)%', $headers[0], $status_code)) {
      return null;
    }
    switch( $status_code[1] ) {
      case '200':
        $parsed = Http::parse_headers(substr($message,
                                           $head_end + strlen(DOUBLE_ENTER)));
        return is_null($parsed)?$headers:$parsed;
      break;
      default:
        return $headers;
      break;
    }
  }
  
  /**
   * @access private
   */
  static protected function get_headers_x($heads, $format=0) {
    $fp = explode(ENTER, $heads);
    $headers = array();
    foreach($fp as $header){
      if($header == "") {
        $eoheader = true;
        break;
      } else {
        $header = trim($header);
      }
  
      if($format == 1) {
        $key = array_shift(explode(':',$header));
        if($key == $header) {
          $headers[] = $header;
        } else {
          $headers[$key]=substr($header,strlen($key)+2);
        }
        unset($key);
      } else {
       $headers[] = $header;
      }
    }
    return $headers;
  }
  
  static protected function get_body_x($heads){
    $fp = explode(DOUBLE_ENTER, $heads, 2);
    return $fp[1];
  }
}

class HttpException extends Exception {
  
}
